﻿using Caliburn.Micro;
using Caliburn.Micro.Logging.log4net;
using myapp.Instances;
using myapp.ViewModels;
using myappcore.ViewModels;
using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace myapp.Bootstrapper
{
    /// <summary>
    /// Bootstrapper
    /// </summary>
    public class AppBootstrapper : Bootstrapper<IShell>
    {
        #region Attribute
        /// <summary>
        /// CompositionContainer container
        /// </summary>
        private CompositionContainer _container;
        #endregion

        #region Properties

        #endregion

        #region Constructure
        static AppBootstrapper()
        {
            LogManager.GetLog = type => new log4netLogger(type);
        }
        #endregion

        #region Method
        /// <summary>
        /// Configure
        /// </summary>
        protected override void Configure()
        {
            _container = new CompositionContainer(
                new AggregateCatalog(AssemblySource.Instance.Select(x => new AssemblyCatalog(x)))
                );

            var batch = new CompositionBatch();

            batch.AddExportedValue<IWindowManager>(new WindowManager());
            batch.AddExportedValue<IEventAggregator>(new EventAggregator());
            batch.AddExportedValue(_container);

            _container.Compose(batch);


        }

        /// <summary>
        /// GetInstance
        /// </summary>
        /// <param name="serviceType"></param>
        /// <param name="key"></param>
        /// <returns></returns>
        protected override object GetInstance(Type serviceType, string key)
        {
            string contract = string.IsNullOrEmpty(key) ? AttributedModelServices.GetContractName(serviceType) : key;
            var exports = _container.GetExportedValues<object>(contract);

            if (exports.Count() > 0)
                return exports.First();

            throw new Exception(string.Format("Could not locate any instances of contract {0}.", contract));
        }

        /// <summary>
        /// GetAllInstances
        /// </summary>
        /// <param name="serviceType"></param>
        /// <returns></returns>
        protected override IEnumerable<object> GetAllInstances(Type serviceType)
        {
            return _container.GetExportedValues<object>(AttributedModelServices.GetContractName(serviceType));
        }

        /// <summary>
        /// BuildUp
        /// </summary>
        /// <param name="instance"></param>
        protected override void BuildUp(object instance)
        {
            _container.SatisfyImportsOnce(instance);
        }

        #endregion
    }

}
